home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH6 / SRC / BEZIER2.FRM < prev    next >
Text File  |  1996-04-01  |  9KB  |  335 lines

  1. VERSION 4.00
  2. Begin VB.Form BezierForm 
  3.    Caption         =   "Bezier Curve"
  4.    ClientHeight    =   5490
  5.    ClientLeft      =   2175
  6.    ClientTop       =   930
  7.    ClientWidth     =   4830
  8.    Height          =   6180
  9.    Left            =   2115
  10.    LinkTopic       =   "Form1"
  11.    ScaleHeight     =   366
  12.    ScaleMode       =   3  'Pixel
  13.    ScaleWidth      =   322
  14.    Top             =   300
  15.    Width           =   4950
  16.    Begin VB.CommandButton CmdNew 
  17.       Caption         =   "New"
  18.       Enabled         =   0   'False
  19.       Height          =   375
  20.       Left            =   4320
  21.       TabIndex        =   5
  22.       Top             =   0
  23.       Width           =   495
  24.    End
  25.    Begin VB.CommandButton CmdGo 
  26.       Caption         =   "Go"
  27.       Default         =   -1  'True
  28.       Enabled         =   0   'False
  29.       Height          =   375
  30.       Left            =   3600
  31.       TabIndex        =   4
  32.       Top             =   0
  33.       Width           =   495
  34.    End
  35.    Begin VB.CheckBox ControlCheck 
  36.       Caption         =   "Show Control Points"
  37.       Height          =   255
  38.       Left            =   1080
  39.       TabIndex        =   3
  40.       Top             =   60
  41.       Value           =   1  'Checked
  42.       Width           =   1815
  43.    End
  44.    Begin VB.TextBox DtText 
  45.       Height          =   285
  46.       Left            =   240
  47.       TabIndex        =   2
  48.       Text            =   "0.01"
  49.       Top             =   45
  50.       Width           =   615
  51.    End
  52.    Begin VB.PictureBox Canvas 
  53.       AutoRedraw      =   -1  'True
  54.       Height          =   4815
  55.       Left            =   0
  56.       ScaleHeight     =   317
  57.       ScaleMode       =   3  'Pixel
  58.       ScaleWidth      =   317
  59.       TabIndex        =   0
  60.       Top             =   480
  61.       Width           =   4815
  62.    End
  63.    Begin VB.Label Label1 
  64.       Caption         =   "dt"
  65.       Height          =   255
  66.       Index           =   1
  67.       Left            =   0
  68.       TabIndex        =   1
  69.       Top             =   60
  70.       Width           =   255
  71.    End
  72.    Begin VB.Menu mnuFile 
  73.       Caption         =   "&File"
  74.       Begin VB.Menu mnuFileExit 
  75.          Caption         =   "E&xit"
  76.       End
  77.    End
  78. End
  79. Attribute VB_Name = "BezierForm"
  80. Attribute VB_Creatable = False
  81. Attribute VB_Exposed = False
  82. Option Explicit
  83.  
  84. Const PI = 3.14159
  85.  
  86. Const GAP = 3
  87.  
  88. ' The endpoints are points 1 and 4. The control
  89. ' points are points 2 and 3.
  90. Dim MaxPt As Integer
  91. Dim PtX() As Single
  92. Dim PtY() As Single
  93.  
  94. Dim MakingNew As Boolean
  95.  
  96. ' The index of the point being dragged.
  97. Dim Dragging As Integer
  98.  
  99. Dim oldmode As Integer
  100.  
  101.  
  102. ' ************************************************
  103. ' The blending function for i, N, and t.
  104. ' ************************************************
  105. Function Blend(i As Integer, N As Integer, t As Single) As Single
  106.     Blend = Factorial(N) / Factorial(i) / _
  107.         Factorial(N - i) * t ^ i * (1 - t) ^ (N - i)
  108. End Function
  109.  
  110. ' ************************************************
  111. ' Draw the curve on the indicated picture box.
  112. ' ************************************************
  113. Sub DrawCurve(pic As PictureBox, start_t As Single, stop_t As Single, dt As Single)
  114. Dim x1 As Single
  115. Dim y1 As Single
  116. Dim t As Single
  117.  
  118.     x1 = X(start_t)
  119.     y1 = Y(start_t)
  120.     pic.Cls
  121.     pic.CurrentX = x1
  122.     pic.CurrentY = y1
  123.     
  124.     t = start_t + dt
  125.     Do While t < stop_t
  126.         x1 = X(t)
  127.         y1 = Y(t)
  128.         pic.Line -(x1, y1)
  129.         t = t + dt
  130.     Loop
  131.     
  132.     x1 = X(stop_t)
  133.     y1 = Y(stop_t)
  134.     pic.Line -(x1, y1)
  135. End Sub
  136.  
  137. ' ************************************************
  138. ' Return the factorial of a number.
  139. ' ************************************************
  140. Function Factorial(N As Integer) As Long
  141. Dim value As Long
  142. Dim i As Integer
  143.  
  144.     value = 1
  145.     For i = 2 To N
  146.         value = value * i
  147.     Next i
  148.     Factorial = value
  149. End Function
  150.  
  151.  
  152. ' ************************************************
  153. ' The parametric function Y(t).
  154. ' ************************************************
  155. Function Y(t As Single) As Single
  156. Dim i As Integer
  157. Dim value As Single
  158.  
  159.     For i = 0 To MaxPt
  160.         value = value + PtY(i) * Blend(i, MaxPt, t)
  161.     Next i
  162.     Y = value
  163. End Function
  164.  
  165. ' ************************************************
  166. ' The parametric function X(t).
  167. ' ************************************************
  168. Function X(t As Single) As Single
  169. Dim i As Integer
  170. Dim value As Single
  171.  
  172.     For i = 0 To MaxPt
  173.         value = value + PtX(i) * Blend(i, MaxPt, t)
  174.     Next i
  175.     X = value
  176. End Function
  177.  
  178. ' ************************************************
  179. ' Use DrawCurve to draw the Bezier curve.
  180. ' ************************************************
  181. Private Sub DrawBezier()
  182. Const DOTTED = 2
  183.  
  184. Dim dt As Single
  185. Dim i As Integer
  186. Dim oldstyle As Integer
  187.  
  188.     If MaxPt < 0 Then Exit Sub
  189.     
  190.     dt = CSng(DtText.Text)
  191.     DrawCurve Canvas, 0, 1, dt
  192.  
  193.     If ControlCheck.value = vbChecked Then
  194.         ' Draw the control points.
  195.         For i = 0 To MaxPt
  196.             Canvas.Line _
  197.                 (PtX(i) - GAP, PtY(i) - GAP)- _
  198.                 Step(2 * GAP, 2 * GAP), , BF
  199.         Next i
  200.         
  201.         ' Connect the control points.
  202.         oldstyle = Canvas.DrawStyle
  203.         Canvas.DrawStyle = DOTTED
  204.         Canvas.CurrentX = PtX(0)
  205.         Canvas.CurrentY = PtY(0)
  206.         For i = 1 To MaxPt
  207.             Canvas.Line -(PtX(i), PtY(i))
  208.         Next i
  209.         Canvas.DrawStyle = oldstyle
  210.     End If
  211. End Sub
  212.  
  213. ' ************************************************
  214. ' Either collect a new point or select a point and
  215. ' start dragging it.
  216. ' ************************************************
  217. Private Sub Canvas_MouseDown(button As Integer, Shift As Integer, X As Single, Y As Single)
  218. Dim i As Integer
  219.  
  220.     ' If we are selecting points, do so now.
  221.     If MakingNew Then
  222.         MaxPt = MaxPt + 1
  223.         ReDim Preserve PtX(0 To MaxPt)
  224.         ReDim Preserve PtY(0 To MaxPt)
  225.         PtX(MaxPt) = X
  226.         PtY(MaxPt) = Y
  227.         Canvas.Line _
  228.             (X - GAP, Y - GAP)- _
  229.             Step(2 * GAP, 2 * GAP), , BF
  230.         
  231.         If MaxPt >= 3 Then CmdGo.Enabled = True
  232.         
  233.         Exit Sub
  234.     End If
  235.  
  236.     ' Otherwise start dragging a point.
  237.     ' Find a close point.
  238.     For i = 0 To MaxPt
  239.         If Abs(PtX(i) - X) <= GAP And _
  240.            Abs(PtY(i) - Y) <= GAP Then Exit For
  241.     Next i
  242.     If i > MaxPt Then Exit Sub
  243.  
  244.     Dragging = i
  245.     oldmode = Canvas.DrawMode
  246.     Canvas.DrawMode = vbInvert
  247.     PtX(Dragging) = X
  248.     PtY(Dragging) = Y
  249.     Canvas.Line _
  250.         (PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
  251.         Step(2 * GAP, 2 * GAP), , BF
  252. End Sub
  253.  
  254.  
  255. ' ************************************************
  256. ' Continue dragging a point.
  257. ' ************************************************
  258. Private Sub Canvas_MouseMove(button As Integer, Shift As Integer, X As Single, Y As Single)
  259.     If Dragging < 0 Then Exit Sub
  260.     
  261.     Canvas.Line _
  262.         (PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
  263.         Step(2 * GAP, 2 * GAP), , BF
  264.     
  265.     PtX(Dragging) = X
  266.     PtY(Dragging) = Y
  267.     
  268.     Canvas.Line _
  269.         (PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
  270.         Step(2 * GAP, 2 * GAP), , BF
  271. End Sub
  272.  
  273.  
  274. ' ************************************************
  275. ' Finish the drag and redraw the curve.
  276. ' ************************************************
  277. Private Sub Canvas_MouseUp(button As Integer, Shift As Integer, X As Single, Y As Single)
  278.     If Dragging < 0 Then Exit Sub
  279.     
  280.     Canvas.DrawMode = oldmode
  281.     
  282.     PtX(Dragging) = X
  283.     PtY(Dragging) = Y
  284.     Dragging = -1
  285.     
  286.     DrawBezier
  287. End Sub
  288.  
  289.  
  290.  
  291.  
  292. Private Sub CmdGo_Click()
  293.     MakingNew = False
  294.     CmdNew.Enabled = True
  295.     DrawBezier
  296. End Sub
  297.  
  298. ' ************************************************
  299. ' Prepare to get new points.
  300. ' ************************************************
  301. Private Sub CmdNew_Click()
  302.     MaxPt = -1
  303.     CmdGo.Enabled = False
  304.     CmdNew.Enabled = False
  305.     MakingNew = True
  306.     Canvas.Cls
  307. End Sub
  308.  
  309. Private Sub ControlCheck_Click()
  310.     DrawBezier
  311. End Sub
  312.  
  313. Private Sub Form_Load()
  314.     MakingNew = True
  315.     MaxPt = -1
  316.     Dragging = -1
  317. End Sub
  318.  
  319. ' ************************************************
  320. ' Make the canvas as big as possible.
  321. ' ************************************************
  322. Private Sub Form_Resize()
  323.     Canvas.Move 0, Canvas.Top, _
  324.         ScaleWidth, ScaleHeight - Canvas.Top
  325.         
  326.     DrawBezier
  327. End Sub
  328.  
  329.  
  330. Private Sub mnuFileExit_Click()
  331.     Unload Me
  332. End Sub
  333.  
  334.  
  335.